<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/3/19
 * Time: 23:18
 */
/****
 * 抽奖
 */
/**
 * 拼手气红包函数
 * @param int $fee 红包总金额
 * @param int $c 发给多少人
 * @return array
 */
function RedEnvelope($fee, $c)
{
//    $fee = 100;
    $n = $fee / 2;
    for ($i = 0; $i < $c; $i++) {
        if ($i == ($c - 1)) {
            $arr[] = $fee;
        } else {
            $arr[] = $j = rand(0.01, $n) + rand(11, 99) / 100;
            $fee = $fee - $j;
            $n = $fee / 4;
        }
    }
    return $arr;
}

//var_dump(RedEnvelope(100,5));

//$arr=RedEnvelope(50,5);
//prt($arr);
//$z =0;
//foreach($arr as $v){
//    $z +=$v;
//    echo $v."+";
//}
//echo "=",$z;

/*************************抽奖算法***********************************/
/**
 * 算法一 全概率计算
 * @param array $p array('a'=>0.5,'b'=>0.2,'c'=>0.4)
 * @return string 返回上面数组的key
 */
function random($ps)
{
    static $arr = array();
    $key = md5(serialize($ps));

    if (!isset($arr[$key])) {
        $max = array_sum($ps);
        foreach ($ps as $k => $v) {
            $v = $v / $max * 10000;
            for ($i = 0; $i < $v; $i++) $arr[$key][] = $k;
        }
    }
    return $arr[$key][mt_rand(0, count($arr[$key]) - 1)];
}

//$arr=array('a'=>0.5,'b'=>0.2,'c'=>0.4);
//prt(random($arr));


/*算法二是一段经典的概率算法，$proArr是一个预先设置的数组，假设数组为：array(100,200,300，400)，
开始是从1,1000这个概率范围内筛选第一个数是否在他的出现概率范围之内， 如果不在，则将概率空减，
也就是k的值减去刚刚的那个数字的概率空间，在本例当中就是减去100，也就是说第二个数是在1，900这个范围内筛选的。
这样筛选到最终，总会有一个数满足要求。就相当于去一个箱子里摸东西，第一个不是，第二个不是，第三个还不是，那最后一个一定是。
这个算法简单，而且效率非常高，关键是这个算法已在我们以前的项目中有应用，尤其是大数据量的项目中效率非常棒。*/

/**
 * 中奖概率算法
 * @param array $proArr 以奖品id为键，中奖概率整数为值的数组
 * @return int|string  根据概率获取奖项id
 */
function get_rand($proArr)
{
    $result = '';//中奖结果

    //概率数组的总概率精度
    $proSum = array_sum($proArr);//将数组中的所有值的和以整数或浮点数的结果返回

    //概率数组循环
    foreach ($proArr as $key => $proCur) {
        $randNum = mt_rand(1, $proSum);//mt_rand — 生成更好的随机数
        if ($randNum <= $proCur) {
            $result = $key;
            break;
        } else {
            $proSum -= $proCur;
        }
    }
    unset ($proArr);

    return $result;
}

//$prize_arr = array(
//    '0' => array('id'=>1,'prize'=>'平板电脑','v'=>1),
//    '1' => array('id'=>2,'prize'=>'数码相机','v'=>5),
//    '2' => array('id'=>3,'prize'=>'音箱设备','v'=>10),
//    '3' => array('id'=>4,'prize'=>'4G优盘','v'=>12),
//    '4' => array('id'=>5,'prize'=>'10Q币','v'=>22),
//    '5' => array('id'=>6,'prize'=>'下次没准就能中哦','v'=>50),
//);
/*
  * $prize_arr是一个二维数组，记录了所有本次抽奖的奖项信息，其中id表示中奖等级，prize表示奖品，v表示中奖概率。
  * 注意其中的v必须为整数，你可以将对应的奖项的v设置成0，即意味着该奖项抽中的几率是0，数组中v的总和（基数），
  * 基数越大越能体现概率的准确性。本例中v的总和为100，那么平板电脑对应的中奖概率就是1%，如果v的总和是10000，那中奖概率就是万分之一了。

每次前端页面的请求，PHP循环奖项设置数组，通过概率计算函数get_rand获取抽中的奖项id。将中奖奖品保存在数组$res['yes']中，
 而剩下的未中奖的信息保存在$res['no']中，最后输出json个数数据给前端页面。
  * */
//如果中奖数据是放在数据库里，这里就需要进行判断中奖数量
//在中1、2、3等奖的，如果达到最大数量的则unset相应的奖项，避免重复中大奖


/*//code here eg:unset($prize_arr['0'])
foreach ($prize_arr as $key => $val) {
    $arr[$val['id']] = $val['v'];
}
//prt($arr);
$rid = get_rand($arr); //根据概率获取奖项id
//prt($rid);
$res['yes'] = $prize_arr[$rid-1]['prize']; //中奖项
//将中奖项从数组中剔除，剩下未中奖项，如果是数据库验证，这里可以省掉
unset($prize_arr[$rid-1]);
shuffle($prize_arr); //打乱数组顺序
for($i=0;$i<count($prize_arr);$i++){
    $pr[] = $prize_arr[$i]['prize'];
}
$res['no'] = $pr;
prt($res);*/
//echo json_encode($res);

/************************促销/优惠/折扣码***********************************/
/**
 * 生成vip激活码
 * @param int $nums 生成多少个优惠码
 * @param array $exist_array 排除指定数组中的优惠码
 * @param int $code_length 生成优惠码的长度
 * @param int $prefix 生成指定前缀
 * @return array                 返回优惠码数组
 */
function generateCode($nums, $exist_array = '', $code_length = 6, $prefix = '')
{

//    $characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";//由数字和大写字母组成
    $characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz";//由数字、大写字母和小写字母组成
//    $characters = "0123456789";//由纯数字组成

    $promotion_codes = array();//这个数组用来接收生成的优惠码

    for ($j = 0; $j < $nums; $j++) {

        $code = '';

        for ($i = 0; $i < $code_length; $i++) {

            $code .= $characters[mt_rand(0, strlen($characters) - 1)];

        }

        //如果生成的4位随机数不再我们定义的$promotion_codes数组里面
        if (!in_array($code, $promotion_codes)) {

            if (is_array($exist_array)) {

                if (!in_array($code, $exist_array)) {//排除已经使用的优惠码

                    $promotion_codes[$j] = $prefix . $code; //将生成的新优惠码赋值给promotion_codes数组

                } else {

                    $j--;

                }

            } else {

                $promotion_codes[$j] = $prefix . $code;//将优惠码赋值给数组

            }

        } else {
            $j--;
        }
    }

    return $promotion_codes;
}
